我正在尝试使用GLSL进行视频处理。我正在使用OpenCV打开视频文件并将每个帧作为单个图像然后我想在GLSL着色器中使用每个帧
使用GLSL视频的最佳/理想/智能解决方案是什么?
VideoCapture cap("movie.MOV");
Mat image;
bool success = cap.read(image);
if(!success)
{
printf("Could not grab a frame\n\7");
exit(0);
}
GLuint tex;
glGenTextures(1, tex);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.cols, image.rows, 0,
GL_BGR, GL_UNSIGNED_BYTE, image.data);
glUniform1i(glGetUniformLocation(shaderProgram, "Texture"), 0);
我是否每次都需要重新编译/重新连接/重新链接我的着色器?或者一旦我的着色器被创建和编译,我使用glUseProgram(shaderProgram)
我可以继续发送新的纹理吗?
我用来向屏幕渲染纹理的当前循环如下。我如何使其适应视频?我需要在哪里调用以更新着色器中使用的纹理?
while(!glfwWindowShouldClose(window))
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0,0,512,512);
glBindFramebuffer(GL_READ_FRAMEBUFFER, frameBuffer);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBlitFramebuffer(0, 0, image.cols, image.rows, 0, 0, image.cols, image.rows, GL_COLOR_BUFFER_BIT, GL_LINEAR);
glfwSwapBuffers(window);
glfwPollEvents();
}
答案 0 :(得分:3)
让我们澄清一些需要在循环之前发生的事情:
glPixelStorei()
; glGenTextures()
生成一个纹理,因为在循环的每次迭代中,其内容都将替换为新数据; glCompileShader()
编译着色器,使用glCreateShader()
创建着色器对象,调用glCreateProgram()
创建程序,调用glAttachShader()
将着色器对象附加到新程序,最后glLinkProgram()
让一切准备就绪。 那就是说,循环的每次迭代都必须:
glTranslatef()
; glTexImage2D()
将帧传输到GPU; glUseProgram()
以激活您的GLSL着色器; GL_QUADS
或其他任何内容绘制2D脸部; glUseProgram(0)
; glDisable(GL_TEXTURE_YOUR_TEXTURE_TARGET)
; 这或多或少需要做什么。
顺便提一下:here's my OpenCV/OpenGL/Qt application从相机中检索帧并将其显示在窗口中。但是没有着色器。
祝你好运!答案 1 :(得分:1)
您不需要使用帧缓冲区将纹理发送到着色器。一旦您将纹理0选为活动纹理并将0设置为着色器中均匀sampler2D的值,每次调用glBindTexture()
时,它都会将sampler2D设置为您使用的纹理。 ve在函数参数中指定。所以不,每次想要改变纹理时,都不需要重新链接或重新编译着色器。