130 if (itsDisplay == EGL_NO_DISPLAY) initDisplay();
132 if (src.type() != CV_8UC1 && src.type() != CV_8UC4)
LFATAL(
"Source pixel format must be CV_8UC1 or CV_8UC4");
133 if (dst.type() != CV_8UC2 && dst.type() != CV_8UC4)
LFATAL(
"Dest pixel format must be CV_8UC2 or CV_8UC4");
134 GLuint
const srcformat = (src.channels() == 4 ? GL_RGBA : GL_LUMINANCE);
135 GLuint
const dstformat = (dst.channels() == 4 ? GL_RGBA4 : GL_RGB565);
138 if (!itsSrcTex || itsSrcTex->Width != src.cols || itsSrcTex->Height != src.rows || itsSrcTex->Format != srcformat)
140 itsSrcTex.reset(
new GPUtexture(src.cols, src.rows, srcformat,
false));
141 LINFO(
"Input texture " << itsSrcTex->Width <<
'x' << itsSrcTex->Height <<
' ' <<
142 (srcformat == GL_RGBA ?
"RGBA" :
"LUMINANCE") <<
" ready.");
146 if (itsRenderbufferId == 0 ||
int(itsRenderWidth) != dst.cols ||
int(itsRenderHeight) != dst.rows ||
147 itsRenderType != dst.type())
149 if (itsRenderbufferId) glDeleteRenderbuffers(1, &itsRenderbufferId);
150 if (itsFramebufferId) glDeleteFramebuffers(1, &itsFramebufferId);
152 GL_CHECK(glGenFramebuffers(1, &itsFramebufferId));
153 GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, itsFramebufferId));
155 GL_CHECK(glGenRenderbuffers(1, &itsRenderbufferId));
156 GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, itsRenderbufferId));
157 GL_CHECK(glRenderbufferStorage(GL_RENDERBUFFER, dstformat, dst.cols, dst.rows));
158 GL_CHECK(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, itsRenderbufferId));
160 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
161 LFATAL(
"Framebuffer creation failed");
163 itsRenderWidth = dst.cols; itsRenderHeight = dst.rows; itsRenderType = dst.type();
164 LINFO(
"Render buffer " << itsRenderWidth <<
'x' << itsRenderHeight <<
' ' <<
165 (dst.channels() == 2 ?
"RGB565" :
"RGBA") <<
" ready.");
169 if (itsQuadVertexBuffer == 0)
172 static GLfloat
const qv[] =
173 { 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
175 GL_CHECK(glGenBuffers(1, &itsQuadVertexBuffer));
176 glBindBuffer(GL_ARRAY_BUFFER, itsQuadVertexBuffer);
177 glBufferData(GL_ARRAY_BUFFER,
sizeof(qv), qv, GL_STATIC_DRAW);
178 GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0));
182 glClearColor(0.15f, 0.25f, 0.35f, 1.0f);
183 glClear(GL_COLOR_BUFFER_BIT);
186 itsSrcTex->setPixels(src.data);
189 GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, itsFramebufferId));
190 GL_CHECK(glViewport(0, 0, itsRenderWidth, itsRenderHeight));
193 if (itsProgramChanged)
195 std::lock_guard<std::mutex> _(itsMutex);
201 itsProgram.reset(
new GPUprogram(itsVshader.c_str(), itsFshader.c_str()));
202 itsProgramChanged =
false;
205 glUseProgram(itsProgram->id());
208 GLuint i = itsProgram->id();
209 for (
auto const & p : itsProgramParams)
211 char const * n = p.first.c_str();
212 float const * v = &p.second.val[0];
213 switch (p.second.type)
215 case F2:
GL_CHECK(glUniform2f(glGetUniformLocation(i, n), v[0], v[1]));
break;
216 case F1:
GL_CHECK(glUniform1f(glGetUniformLocation(i, n), v[0]));
break;
217 case I2:
GL_CHECK(glUniform2i(glGetUniformLocation(i, n),
int(v[0]),
int(v[1])));
break;
218 case I1:
GL_CHECK(glUniform1i(glGetUniformLocation(i, n),
int(v[0])));
break;
219 default:
LFATAL(
"Unsupported GPU program parameter type " << p.second.type);
224 if (!itsProgram)
LFATAL(
"You need to set a program before processing frames");
227 glUniform2f(glGetUniformLocation(itsProgram->id(),
"texelsize"), 1.0f / dst.cols, 1.0f / dst.rows);
228 glUniform1i(glGetUniformLocation(itsProgram->id(),
"tex"), 0);
231 GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, itsQuadVertexBuffer));
232 GL_CHECK(glActiveTexture(GL_TEXTURE0));
233 GL_CHECK(glBindTexture(GL_TEXTURE_2D, itsSrcTex->Id));
235 GLuint loc = glGetAttribLocation(itsProgram->id(),
"vertex");
236 GL_CHECK(glVertexAttribPointer(loc, 4, GL_FLOAT, 0, 16, 0));
237 GL_CHECK(glEnableVertexAttribArray(loc));
238 GL_CHECK(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
241 GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, itsFramebufferId));
242 if (dstformat == GL_RGBA4)
GL_CHECK(glReadPixels(0, 0, dst.cols, dst.rows, GL_RGBA, GL_UNSIGNED_BYTE, dst.data));
243 else GL_CHECK(glReadPixels(0, 0, dst.cols, dst.rows, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, dst.data));
244 GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0));
Simple class to hold an OpenGL texture.