summaryrefslogtreecommitdiff
path: root/gui/src/ofxGpuLutBlend.cpp
blob: 85a08114be622de6d1f68391e18aa256d328b0ac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include "ofxGpuLutBlend.h"

ofxGpuLutBlend::ofxGpuLutBlend(){}
ofxGpuLutBlend::~ofxGpuLutBlend(){}

void ofxGpuLutBlend::load(ofTexture lutTexture){
    
    if(ofIsGLProgrammableRenderer()){
        vertexShader = "#version 150\n";
        vertexShader += STRINGIFY(
                                  uniform mat4 projectionMatrix;
                                  uniform mat4 modelViewMatrix;
                                  uniform mat4 modelViewProjectionMatrix;
                                  
                                  in vec4  position;
                                  in vec2  texcoord;
                                  
                                  out vec2 texCoordVarying;
                                  
                                  void main()
                                  {
                                      texCoordVarying = texcoord;
                                      gl_Position = modelViewProjectionMatrix * position;
                                  }
                                  );
        
        fragmentShader = "#version 150\n";
        fragmentShader += STRINGIFY(
                                    uniform sampler2DRect tex;
                                    uniform sampler2DRect lut;
                                    uniform float blend;
                                    
                                    in vec2 texCoordVarying;
                                    
                                    out vec4 fragColor;
                                    
                                    // Texture coordinates
                                    vec2 texcoord0 = texCoordVarying;
                                    
                                    float size = 64.0;
                                    
                                    void main( void )
                                    {
                                        vec3 rawColor = texture(tex, texcoord0).rgb;
                                        //float rawAlpha = texture(tex, texcoord0).a;
                                        
                                        if (rawAlpha <= 0.0) {
                                            fragColor = vec4(rawColor, 0.0);
                                        }
                                        else {
                                            vec3 originalColor = floor(texture(tex, texcoord0).rgb * vec3(size - 1.0));
                                            vec2 blueIndex = vec2(mod(originalColor.b, sqrt(size)), floor(originalColor.b / sqrt(size)));
                                            vec2 index = vec2((size * blueIndex.x + originalColor.r) + 0.5, (size * blueIndex.y + originalColor.g) + 0.5);
                                            fragColor = vec4(texture(lut, index).rgb, blend);
                                        }
                                    }
                                    );
        
        lutShader.setupShaderFromSource(GL_VERTEX_SHADER, vertexShader);
        lutShader.setupShaderFromSource(GL_FRAGMENT_SHADER, fragmentShader);
        lutShader.bindDefaults();
        lutShader.linkProgram();
    }
    else {
        fragmentShader = "#version 120\n#extension GL_ARB_texture_rectangle : enable\n";
        fragmentShader += STRINGIFY(
                                    uniform sampler2DRect tex;
                                    uniform sampler2DRect lut;
                                    uniform float blend;
                                    
                                    float size = 64.0;
                                    
                                    void main( void )
                                    {
                                        vec3 rawColor = texture2DRect(tex, gl_TexCoord[0].st).rgb;
                                        //float rawAlpha = texture2DRect(tex, gl_TexCoord[0].st).a;
                                        
                                        if (blend <= 0.0) {
                                            gl_FragColor = vec4(rawColor, 0.0);
                                        }
                                        else {
                                            vec3 originalColor = floor(texture2DRect(tex, gl_TexCoord[0].st).rgb * vec3(size - 1.0));
                                            vec2 blueIndex = vec2(mod(originalColor.b, sqrt(size)), floor(originalColor.b / sqrt(size)));
                                            vec2 index = vec2((size * blueIndex.x + originalColor.r) + 0.5, (size * blueIndex.y + originalColor.g) + 0.5);
                                            gl_FragColor = vec4(texture2DRect(lut, index).rgb, blend);
                                        }
                                    }
                                    );
        
        
        lutShader.unload();
        lutShader.setupShaderFromSource(GL_FRAGMENT_SHADER, fragmentShader);
        lutShader.linkProgram();
    }
    
    lut.setTextureWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
    lut.setTextureMinMagFilter(GL_NEAREST, GL_NEAREST);
    if(!ofGetUsingArbTex()){
        ofEnableArbTex();
        lut = lutTexture;
        ofDisableArbTex();
    }else{
        lut = lutTexture;
    }
    blendAmt=1.0f;
}
void ofxGpuLutBlend::setBlend(float amt){
    blendAmt=amt;
}
void ofxGpuLutBlend::load(ofImage lutImage){
    load(lutImage.getTexture());
}

void ofxGpuLutBlend::load(string path){
    lutImage.load(path);
    load(lutImage.getTexture());
}

void ofxGpuLutBlend::begin(){
    lutShader.begin();
    lutShader.setUniformTexture("lut", lut, 1);
    lutShader.setUniform1f("blend", blendAmt);
}

void ofxGpuLutBlend::end(){
    lutShader.end();
}