diff options
Diffstat (limited to 'intern/opencolorio')
-rw-r--r-- | intern/opencolorio/CMakeLists.txt | 1 | ||||
-rw-r--r-- | intern/opencolorio/SConscript | 1 | ||||
-rw-r--r-- | intern/opencolorio/fallback_impl.cc | 12 | ||||
-rw-r--r-- | intern/opencolorio/ocio_capi.cc | 15 | ||||
-rw-r--r-- | intern/opencolorio/ocio_capi.h | 6 | ||||
-rw-r--r-- | intern/opencolorio/ocio_impl.cc | 235 | ||||
-rw-r--r-- | intern/opencolorio/ocio_impl.h | 12 | ||||
-rw-r--r-- | intern/opencolorio/ocio_impl_glsl.cc | 274 |
8 files changed, 556 insertions, 0 deletions
diff --git a/intern/opencolorio/CMakeLists.txt b/intern/opencolorio/CMakeLists.txt index c281a6e7bbb..91bf6550f27 100644 --- a/intern/opencolorio/CMakeLists.txt +++ b/intern/opencolorio/CMakeLists.txt @@ -52,6 +52,7 @@ if(WITH_OPENCOLORIO) list(APPEND SRC ocio_impl.cc + ocio_impl_glsl.cc ) if(WIN32 AND NOT MINGW) diff --git a/intern/opencolorio/SConscript b/intern/opencolorio/SConscript index 6e7c467f64f..e4a0d3ebb7c 100644 --- a/intern/opencolorio/SConscript +++ b/intern/opencolorio/SConscript @@ -40,5 +40,6 @@ if env['WITH_BF_OCIO']: incs += ' ' + env['BF_BOOST_INC'] else: sources.remove('ocio_impl.cc') + sources.remove('ocio_impl_glsl.cc') env.BlenderLib( 'bf_intern_opencolorio', sources, Split(incs), defs, libtype=['extern','player'], priority=[10, 185]) diff --git a/intern/opencolorio/fallback_impl.cc b/intern/opencolorio/fallback_impl.cc index d01d8d4c8f4..47c648e9cba 100644 --- a/intern/opencolorio/fallback_impl.cc +++ b/intern/opencolorio/fallback_impl.cc @@ -380,3 +380,15 @@ void FallbackImpl::matrixTransformRelease(OCIO_MatrixTransformRcPtr *) void FallbackImpl::matrixTransformScale(float * , float * , const float *) { } + +void FallbackImpl::setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor) +{ +} + +void FallbackImpl::finishGLSLDraw(OCIO_GLSLDrawState *state) +{ +} + +void FallbackImpl::freeGLState(struct OCIO_GLSLDrawState *state_r) +{ +} diff --git a/intern/opencolorio/ocio_capi.cc b/intern/opencolorio/ocio_capi.cc index 4f839a61fad..73d8af295f2 100644 --- a/intern/opencolorio/ocio_capi.cc +++ b/intern/opencolorio/ocio_capi.cc @@ -282,3 +282,18 @@ void OCIO_matrixTransformScale(float * m44, float * offset4, const float *scale4 { impl->matrixTransformScale(m44, offset4, scale4f); } + +void OCIO_setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor) +{ + impl->setupGLSLDraw(state_r, processor); +} + +void OCIO_finishGLSLDraw(struct OCIO_GLSLDrawState *state) +{ + impl->finishGLSLDraw(state); +} + +void OCIO_freeOGLState(struct OCIO_GLSLDrawState *state) +{ + impl->freeGLState(state); +} diff --git a/intern/opencolorio/ocio_capi.h b/intern/opencolorio/ocio_capi.h index 19fd8fe643b..3c42e0a1a1e 100644 --- a/intern/opencolorio/ocio_capi.h +++ b/intern/opencolorio/ocio_capi.h @@ -32,6 +32,8 @@ extern "C" { #endif +struct OCIO_GLSLDrawState; + #define OCIO_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name #define OCIO_ROLE_SCENE_LINEAR "scene_linear" @@ -119,6 +121,10 @@ void OCIO_matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt); void OCIO_matrixTransformScale(float * m44, float * offset4, const float * scale4); +void OCIO_setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor); +void OCIO_finishGLSLDraw(struct OCIO_GLSLDrawState *state); +void OCIO_freeOGLState(struct OCIO_GLSLDrawState *state); + #ifdef __cplusplus } #endif diff --git a/intern/opencolorio/ocio_impl.cc b/intern/opencolorio/ocio_impl.cc index b073a038f0d..8803814ce3f 100644 --- a/intern/opencolorio/ocio_impl.cc +++ b/intern/opencolorio/ocio_impl.cc @@ -26,8 +26,16 @@ */ #include <iostream> +#include <sstream> #include <string.h> +#ifdef __APPLE__ +#include <OpenGL/gl.h> +#include <OpenGL/glu.h> +#else +#include <GL/glew.h> +#endif + #include <OpenColorIO/OpenColorIO.h> using namespace OCIO_NAMESPACE; @@ -50,6 +58,8 @@ using namespace OCIO_NAMESPACE; #define MEM_NEW(type) new(MEM_mallocN(sizeof(type), __func__)) type() #define MEM_DELETE(what, type) if(what) { ((type*)(what))->~type(); MEM_freeN(what); } (void)0 +static const int LUT3D_EDGE_SIZE = 32; + static void OCIO_reportError(const char *err) { std::cerr << "OpenColorIO Error: " << err << std::endl; @@ -541,3 +551,228 @@ 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); +} diff --git a/intern/opencolorio/ocio_impl.h b/intern/opencolorio/ocio_impl.h index b6bbc912e5b..2a1f88be5f4 100644 --- a/intern/opencolorio/ocio_impl.h +++ b/intern/opencolorio/ocio_impl.h @@ -95,6 +95,10 @@ public: virtual void matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt) = 0; virtual void matrixTransformScale(float * m44, float * offset4, const float * scale4) = 0; + + virtual void setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor) = 0; + virtual void finishGLSLDraw(struct OCIO_GLSLDrawState *state) = 0; + virtual void freeGLState(struct OCIO_GLSLDrawState *state_r) = 0; }; class FallbackImpl : public IOCIOImpl { @@ -164,6 +168,10 @@ public: void matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt); void matrixTransformScale(float * m44, float * offset4, const float * scale4); + + void setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor); + void finishGLSLDraw(struct OCIO_GLSLDrawState *state); + void freeGLState(struct OCIO_GLSLDrawState *state_r); }; #ifdef WITH_OCIO @@ -234,6 +242,10 @@ public: void matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt); void matrixTransformScale(float * m44, float * offset4, const float * scale4); + + void setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor); + void finishGLSLDraw(struct OCIO_GLSLDrawState *state); + void freeGLState(struct OCIO_GLSLDrawState *state_r); }; #endif diff --git a/intern/opencolorio/ocio_impl_glsl.cc b/intern/opencolorio/ocio_impl_glsl.cc new file mode 100644 index 00000000000..c79593779cf --- /dev/null +++ b/intern/opencolorio/ocio_impl_glsl.cc @@ -0,0 +1,274 @@ +/* + * Adapted from OpenColorIO with this license: + * + * Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. + * All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Sony Pictures Imageworks nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Modifications Copyright 2013, Blender Foundation. + * + * Contributor(s): Sergey Sharybin + * + */ + +#include <sstream> +#include <string.h> + +#ifdef __APPLE__ +#include <OpenGL/gl.h> +#include <OpenGL/glu.h> +#else +#include <GL/glew.h> +#endif + +#include <OpenColorIO/OpenColorIO.h> + +using namespace OCIO_NAMESPACE; + +#include "MEM_guardedalloc.h" + +#include "ocio_impl.h" + +static const int LUT3D_EDGE_SIZE = 32; + + +/* **** OpenGL drawing routines using GLSL for color space transform ***** */ + +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); +} |