使用OpenGL ES着色器在视频上叠加图像

时间:2012-08-31 15:29:45

标签: iphone objective-c opengl-es

我试图了解OpenGL的基本概念。一周之后,我离那里还很远。一旦我在glsl,我知道该怎么做,但我发现那里有棘手的一点。

我目前能够传递我操纵和呈现的视频像素。然后我一直在尝试添加静止图像作为叠加层。这是我迷路的地方。我的最终目标是使用来自我的视频和静止图像的像素数据结束相同的片段着色器。我想这意味着我需要两个纹理并传递两个像素缓冲区。我目前正在传递像这样的视频像素:

glGenTextures(1, &textures[0]);

//target, texture
glBindTexture(GL_TEXTURE_2D, textures[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, buffer);

然后我会在纹理[1]上用图像中的第二个缓冲区重复这个过程吗?如果是,那么我是否然后绑定GL_TEXTURE0和GL_TEXTURE1? ......我的着色器会是这样的吗?

uniform sampler2D videoData;
uniform sampler2D imageData;

一旦我在着色器中?似乎无论我尝试什么组合,图像和视频总是最终只是这两者中的视频数据。

很抱歉这里合并了很多问题,只想清除我的许多假设并继续前进。为了澄清这个问题,我需要做什么才能在描述的过程中从静止图像中添加像素? (“易于理解”的示例代码或任何类型的提示将不胜感激)。

2 个答案:

答案 0 :(得分:2)

自己甚至不打扰写这段代码怎么样?我在开源GPUImage框架中完成了所有这些工作,并设置了一个摄像机源,拉入一个图像,并将该图像覆盖在视频上,可以使用以下代码完成:

videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset640x480 cameraPosition:AVCaptureDevicePositionBack];
filter = [[GPUImageOverlayBlendFilter alloc] init];
[videoCamera addTarget:filter];
inputImage = [UIImage imageNamed:@"WID-small.jpg"];
sourcePicture = [[GPUImagePicture alloc] initWithImage:inputImage smoothlyScaleOutput:YES];
[sourcePicture processImage];            
[sourcePicture addTarget:filter];
[filter addTarget:filterView];
[videoCamera startCameraCapture];

这一切都在幕后使用OpenGL ES 2.0将片段着色器应用于视频帧和静态图像,并且它比我在iOS上所知的任何其他内容都快。对于支持它的设备,我已将其调整为使用一些额外的优化来加速图像和视频帧上传过程。

要在这里回答您的具体问题,是的,您将创建两个纹理制服,就像您在那里展示一样。在使用之前,您需要从链接的着色器程序中获取每个背面的标识符。在您的代码中,您需要将两个纹理绑定到两个不同的纹理单元,然后使用类似于以下的代码将这些纹理单元的值分配给您的制服:

glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, sourceTexture);
glUniform1i(filterInputTextureUniform, 2);  

glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, filterSourceTexture2);                
glUniform1i(filterInputTextureUniform2, 3);

我见过人们常犯的一个错误就是在glUniform1i()处使用纹理名称,而不是纹理绑定的纹理单元。

答案 1 :(得分:0)

您需要使用glActiveTextureARB进行多重纹理 请查看本教程http://www.clockworkcoders.com/oglsl/tutorial8.htm