forked from bartvdbraak/blender
Epic fail in original GLSL display transform commit
Apparently C== allowed to have implementations of OCIOImpl::setupGLSLDraw, OCIOImpl::finishGLSLDraw and OCIOImpl::freeGLState in two different files. STUPID!
This commit is contained in:
parent
689f3aa174
commit
03c337f61c
@ -551,228 +551,3 @@ void OCIOImpl::matrixTransformScale(float * m44, float * offset4, const float *s
|
|||||||
{
|
{
|
||||||
MatrixTransform::Scale(m44, offset4, scale4f);
|
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);
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user