framework2
174 строки · 5.0 Кб
1/*
2* LUTPass.cpp
3*
4* Copyright (c) 2012, Neil Mendoza, http://www.neilmendoza.com
5* All rights reserved.
6*
7* Redistribution and use in source and binary forms, with or without
8* modification, are permitted provided that the following conditions are met:
9*
10* * Redistributions of source code must retain the above copyright notice,
11* this list of conditions and the following disclaimer.
12* * Redistributions in binary form must reproduce the above copyright
13* notice, this list of conditions and the following disclaimer in the
14* documentation and/or other materials provided with the distribution.
15* * Neither the name of Neil Mendoza nor the names of its contributors may be used
16* to endorse or promote products derived from this software without
17* specific prior written permission.
18*
19* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29* POSSIBILITY OF SUCH DAMAGE.
30*
31*/
32#include "LUTPass.h"
33
34namespace itg
35{
36
37LUTPass::LUTPass(const ofVec2f& aspect, bool arb) : RenderPass(aspect, arb, "lut"), lut_tex(0)
38{
39}
40
41LUTPass::~LUTPass()
42{
43dispose();
44}
45
46struct RGB
47{
48float r, g, b;
49};
50
51LUTPass* LUTPass::loadLUT(string path)
52{
53dispose();
54
55vector<RGB> lut;
56int LUT_3D_SIZE = 0;
57
58// load .cube file
59{
60path = ofToDataPath(path);
61
62ifstream ifs(path.c_str());
63
64while (!ifs.eof())
65{
66string line;
67getline(ifs, line);
68
69if (line.empty()) continue;
70
71int v;
72if (sscanf(line.c_str(), "LUT_3D_SIZE %i", &v) == 1)
73{
74LUT_3D_SIZE = v;
75break;
76}
77}
78
79if (LUT_3D_SIZE == 0)
80{
81LUT_3D_SIZE = 32;
82}
83
84while (!ifs.eof())
85{
86string line;
87getline(ifs, line);
88
89if (line.empty()) continue;
90
91RGB v;
92if (sscanf(line.c_str(), "%f %f %f", &v.r, &v.g, &v.b) == 3)
93{
94lut.push_back(v);
95}
96}
97
98if (lut.size() != (LUT_3D_SIZE * LUT_3D_SIZE * LUT_3D_SIZE)) ofLogError() << "LUT size is incorrect.";
99}
100
101// gen texture
102{
103glGenTextures(1, &lut_tex);
104
105glEnable(GL_TEXTURE_3D);
106glBindTexture(GL_TEXTURE_3D, lut_tex);
107
108glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
109
110glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
111glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
112
113glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
114glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);
115glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP);
116
117glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
118
119glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, LUT_3D_SIZE, LUT_3D_SIZE, LUT_3D_SIZE, 0, GL_RGB, GL_FLOAT, &lut[0]);
120
121glBindTexture(GL_TEXTURE_3D, 0);
122
123glDisable(GL_TEXTURE_3D);
124}
125
126// setup shader
127string fragShaderSrc = STRINGIFY(
128uniform sampler2D tex;
129uniform sampler3D lut_tex;
130
131void main()
132{
133vec4 c = texture2D(tex, gl_TexCoord[0].xy);
134vec3 src = c.rgb;
135src = clamp(src, 0., 0.98);
136vec3 dst = texture3D(lut_tex, src).rgb;
137gl_FragColor = gl_Color * vec4(dst, c.a);
138}
139);
140
141shader.setupShaderFromSource(GL_FRAGMENT_SHADER, fragShaderSrc);
142shader.linkProgram();
143
144return this;
145}
146
147void LUTPass::dispose()
148{
149if (lut_tex)
150{
151glDeleteTextures(1, &lut_tex);
152lut_tex = NULL;
153
154shader.unload();
155}
156}
157
158void LUTPass::render(ofFbo& readFbo, ofFbo& writeFbo)
159{
160writeFbo.begin();
161
162shader.begin();
163
164shader.setUniformTexture("tex", readFbo.getTexture(), 0);
165shader.setUniformTexture("lut_tex", GL_TEXTURE_3D, lut_tex, 1);
166
167texturedQuad(0, 0, writeFbo.getWidth(), writeFbo.getHeight());
168
169shader.end();
170
171writeFbo.end();
172}
173
174}